package bll

import (
	"context"

	"auth/model"
	"auth/model/entity"
	"auth/model/mapping"
	"auth/store"
	"auth/store/mysql"
	"time"
)

type user struct {
	iUser store.IUser
}

var User = &user{
	iUser: mysql.User,
}

func init() {
	Register(User)
}

func (a *user) init() func() {
	return func() {}
}

// Create
func (a *user) Create(ctx context.Context, in *model.UserCreateRequest) error {
	var (
		err error
	)
	c := buildUser(in)
	_, err = a.iUser.Create(ctx, c)
	return err
}

// Update
func (a *user) Update(ctx context.Context, in *model.UserUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
	)

	if in.Username != nil {
		dict["username"] = in.Username
	}

	if in.Password != nil {
		dict["password"] = in.Password
	}

	if in.Salt != nil {
		dict["salt"] = in.Salt
	}

	if in.Nickname != nil {
		dict["nickname"] = in.Nickname
	}

	if in.Email != nil {
		dict["email"] = in.Email
	}

	if in.Phone != nil {
		dict["phone"] = in.Phone
	}

	if in.RoleID != nil {
		dict["role_i_d"] = in.RoleID
	}

	if in.Status != nil {
		dict["status"] = in.Status
	}

	if in.ActiveState != nil {
		dict["active_state"] = in.ActiveState
	}

	if in.LastLoginAt != nil {
		dict["last_login_at"] = in.LastLoginAt
	}

	if in.CreatedAt != nil {
		dict["created_at"] = in.CreatedAt
	}

	if in.UpdatedAt != nil {
		dict["updated_at"] = in.UpdatedAt
	}

	// do other update here
	updateAt := time.Now().Unix()
	in.UpdatedAt = &updateAt
	return a.iUser.Update(ctx, in.Id, dict)
}

// Delete
func (a *user) Delete(ctx context.Context, in *model.UserDeleteRequest) error {
	return a.iUser.Delete(ctx, in.Id)
}

// List
func (a *user) List(ctx context.Context, in *model.UserListRequest) (*model.UserListResponse, error) {
	var (
		err   error
		total int
		list  []*entity.User
		out   = &model.UserListResponse{}
	)

	if total, list, err = a.iUser.List(ctx, in); err != nil {
		return nil, err
	}

	out.Total = total
	out.List = mapping.UsersEntityToDto(list)

	return out, nil
}

// Find
func (a *user) Find(ctx context.Context, in *model.UserInfoRequest) (*model.UserInfo, error) {
	var (
		err  error
		data *entity.User
		out  = &model.UserInfo{}
	)

	if data, err = a.iUser.Find(ctx, in); err != nil {
		return nil, err
	}

	out = mapping.UserEntityToDto(data)
	return out, nil
}

// buildUser build entity
func buildUser(in *model.UserCreateRequest) *entity.User {

	ety := &entity.User{

		Id: in.Id,
	}

	ety.Username = in.Username

	ety.Password = in.Password

	ety.Salt = in.Salt

	ety.Nickname = in.Nickname

	ety.Email = in.Email

	ety.Phone = in.Phone

	ety.RoleID = in.RoleID

	ety.Status = in.Status

	ety.ActiveState = in.ActiveState

	ety.LastLoginAt = in.LastLoginAt

	ety.CreatedAt = time.Now().Unix()

	ety.UpdatedAt = in.UpdatedAt

	return ety
}
